package io.renren.modules.clearing.service.impl;

import cn.com.taiji.common.manager.net.http.binclient.ApiRequestException;
import cn.com.taiji.sdk.comm.LwClientHelper;
import cn.com.taiji.sdk.model.comm.protocol.cdts.passTransaction.*;
import cn.com.taiji.sdk.tools.FileTools;
import io.renren.common.utils.*;
import io.renren.modules.clearing.dao.ConfigParaDicDao;
import io.renren.modules.clearing.dao.SeverRunDao;
import io.renren.modules.clearing.dao.ZFKExitWasteDao;
import io.renren.modules.clearing.entity.DataExchangeList;
import io.renren.modules.clearing.entity.SeverRun;
import io.renren.modules.clearing.entity.tbl_ZFKExitWaste;
import io.renren.modules.clearing.service.ETCTransactionUploadService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;

@Service
public class ETCTransactionUploadServiceImpl implements ETCTransactionUploadService {
    private Logger log = LoggerFactory.getLogger(getClass());
    @Autowired
    ConfigParaDicDao configParaDicDao;
    @Autowired
    ZFKExitWasteDao zfkExitWasteDao;
    @Autowired
    SeverRunDao severRunDao;

    @Override
    public List<String> ETCTransactionUpload() throws Exception {

        List<String> netIDList =  new ArrayList<>();
        //检查控制参数是否上传 tbl_configparadic
        log.info("开始检查ETC交易上传控制参数");
        int control = configParaDicDao.checkContolParam(Constants.CONTROL_ETCAUDOWN_PARAM);
        if(control==1){
            //检查待上传数量
            int num = zfkExitWasteDao.getUnUploadCount();
           // int num=(Integer) sqlMapClient.queryForObject("ZfkExitW_ORACLE.getUnUploadCount");
            if(num>= Config.unnum){
                //获取要需上传原始流水的网络编号
                netIDList = zfkExitWasteDao.getNetIDList();
               // netIDList=sqlMapClient.queryForList("ZfkExitW_ORACLE.getNetIDList");
            }else if(num>0){
                //检查待上传时间
                SeverRun serverRun = severRunDao.getServerRun(Constants.CONTROL_ETCTRANSACTIONUPLOAD_PARAM);
                //SeverRun serverRun=(SeverRun) sqlMapClient.queryForObject("Base_ORACLE.getServerRun",Constants.CONTROL_ETCTRANSACTIONUPLOAD_PARAM);

                if(serverRun!=null&& DateUtil.getDateMinute(new Date(), serverRun.getDateValue())>=Config.uploadtime){
                    netIDList = zfkExitWasteDao.getNetIDList();
                    //netIDList=sqlMapClient.queryForList("ZfkExitW_ORACLE.getNetIDList");
                }else{
                    log.info("ETC交易上传待上传数量"+num+"未到上传时间,等待下次执行");
                }

            }else{
                log.info("ETC交易上传待上传数量"+num+"无待上传数据,等待下次执行");
            }

        }else{
            log.info("ETC交易上传接口暂停，任务退出");
        }
        return netIDList;

    }

    @Override
    public boolean SendMsg(String netID) throws Exception {

        boolean change=false;
        List<tbl_ZFKExitWaste> list= new ArrayList<>();
        //获取该包的包号
        //根据需上传流水的网络编号获取交易数据
        Long MessageID=null;

        //根据网络编号先获取是否有上传失败的数据
        MessageID = zfkExitWasteDao.getErrorCountByMessageID(netID);
       // MessageID=(Long) sqlMapClient.queryForObject("ZfkExitW_ORACLE.getErrorCountByMessageID",netID);

        //无失败数据
        if(MessageID==null||MessageID==0){
            change =true;
            MessageID = configParaDicDao.getMessageID(Constants.MESSAGEID_ETCTRANSACTION);
            //MessageID=(Long) sqlMapClient.queryForObject("Base_ORACLE.getMessageID",Constants.MESSAGEID_ETCTRANSACTION);
            MessageID++;
            //根据网络编号取出待上传数据
            list = zfkExitWasteDao.getUploadDataListByNetID(netID);
            //list=sqlMapClient.queryForList("ZfkExitW_ORACLE.getUploadDataListByNetID",netID);
        }else{
            //根据网络编号，交易包号 取出待上传数据

            Map map = new HashMap();
            map.put("messageID",MessageID);
            map.put("netID", netID);
            list = zfkExitWasteDao.getUploadDataListByMessageID(map);
           // list=sqlMapClient.queryForList("ZfkExitW_ORACLE.getUploadDataListByMessageID",map);
        }

        boolean flag=false;

        List<ETCTransactionModel> data= new ArrayList<>();
        //总金额
        long amount=0;
        //TODO 这里需要完善
        for (int i = 0; i < list.size(); i++) {
            tbl_ZFKExitWaste zfk =list.get(i);
            ETCTransactionModel em = new ETCTransactionModel();
            em.setId(zfk.getKeyPressInfo().toString());
            //em.setId(TypeTransUtil.getYgzlaneID(zfk.getExitStationID(),zfk.getExitLaneID())+DateUtil.formatDateTime1(zfk.getExitTime())+CompletionStr.compStr0(zfk.getExitWasteSN()%100+"", 2));

            em.setEnTime(zfk.getEntryStation()==0?DateUtil.formatDateTimes(zfk.getExitTime()):DateUtil.formatDateTimes(zfk.getEntryTime()));
            //计费编号(转)
            em.setFeeId(zfk.getEntryStation()==0?zfk.getCardNetID()+zfk.getPayCardID2()+DateUtil.formatDateTime1(zfk.getExitTime()):zfk.getCardNetID()+zfk.getPayCardID2()+DateUtil.formatDateTime1(zfk.getEntryTime()));
            em.setExDate(DateUtil.dateToOriStr(zfk.getExitTime()));
            em.setExTime(DateUtil.formatTime(zfk.getExitTime()));
            //em.setFee((long) (100*(zfk.getStoreMoney()+zfk.getTallyMoney())));
            em.setFee((long) (zfk.getStoreMoney()+zfk.getTallyMoney()));
            em.setExWeight(zfk.getvClass()<5?0:zfk.getTotalWeight());
            em.setEnWeight(zfk.getvClass()<5?0:zfk.getTotalWeight());
            em.setAxleCount(zfk.getAxleNum());
            em.setAxlsType(zfk.getAxisType().toString());
            em.setPermittedWeight(zfk.getLimitWeight());
            //em.setEnTollLaneId(zfk.getEntryStation()==0?TypeTransUtil.transIDToLaneID(zfk.getKeyPressInfo()):TypeTransUtil.getYgzlaneID(zfk.getEntryStation(),zfk.getEntryLane()));
//			if(zfk.getEntryStation()!=0&&zfk.getEntryLane()==0){
//				em.setEnTollLaneId("000000000000000000000");
//			}
            if(zfk.getEntryStation()!=0&&zfk.getEntryLane()==0){
                em.setEnTollLaneId(TypeTransUtil.getYgzlaneIDByStation(zfk.getEntryStation()));
            }
            if(zfk.getEntryStation()!=0&&zfk.getEntryLane()!=0){
                em.setEnTollLaneId(zfk.getEntryStation()==0?TypeTransUtil.transIDToLaneID(zfk.getKeyPressInfo()):TypeTransUtil.getYgzlaneID(zfk.getEntryStation(),zfk.getEntryLane()));
            }
            if(zfk.getEntryStation()==0){
                em.setEnTollLaneId(TypeTransUtil.transIDToLaneID(zfk.getKeyPressInfo()));
            }



            em.setEtcCardId(zfk.getCardNetID()+zfk.getPayCardID2());
            //em.setCpcCardId(null);
            //em.setSelfServiceCPC(0);
            //em.setElectricalPercentage(0);
            em.setTransNo((long)zfk.getPayCardTranSN());
            em.setTerminalTransNo(CompletionStr.compStr0(Integer.toHexString(Integer.valueOf(zfk.getpSAMTradeSN())), 8));
            if(!"0".equals(zfk.getObuId2())){
                em.setObuid(zfk.getObuId2());
            }



//			if(zfk.getSpare2()>=9 ||zfk.getSpare2()<0){
            if(zfk.getSpare2()==9 ||zfk.getSpare2()<0){
                em.setEnVehicleId(zfk.getvLP()+"_7");
                em.setExVehicleId(zfk.getvLP()+"_7");
                em.setIdentifyVehicleId(zfk.getvLP()+"_9");
            }else{
                em.setEnVehicleId(zfk.getvLP()+"_"+zfk.getSpare2());
                em.setExVehicleId(zfk.getvLP()+"_"+zfk.getSpare2());
                em.setIdentifyVehicleId(zfk.getvLP()+"_"+zfk.getSpare2());
            }

            //em.setEnVehicleType(zfk.getEntryStation()==0?zfk.getvClass():zfk.getEntryVClass());
            em.setEnVehicleType(zfk.getvClass());
            em.setExVehicleType(zfk.getvClass());
            em.setSpecialType("0");//特情
            em.setEnVehicleClass(TypeTransUtil.getVehicleClass(zfk.getvType()));
            em.setVehicleClass(TypeTransUtil.getVehicleClass(zfk.getvType()));
            em.setTac(CompletionStr.compStr0(Long.toHexString(Long.parseLong(zfk.gettAC())), 8));
            em.setTransType(CompletionStr.compStr0(zfk.getTransType()+"", 2));
            em.setTerminalNo(zfk.getTerminalId());
            em.setPreBalance((long)(zfk.getStoreMoney()>0?zfk.getPayCardBalance():0));
            em.setPostBalance((long)(zfk.getStoreMoney()>0?zfk.getStoreBalanceMoney():0));

            em.setEnTollStationName(zfk.getEntryStation()==0?zfk.getExitStationName():zfk.getEntryStationName());
            em.setExTollStationName(zfk.getExitStationName());
            em.setServiceType(1);
            //em.setAlgorithmIdentifier(zfk.getKeyVersion()!=2?1:2);
            em.setAlgorithmIdentifier(1);
            em.setDescription(zfk.getEntryStation()==0?zfk.getExitStationName():zfk.getEntryStationName()+"至"+zfk.getExitStationName());
            em.setMultiProvince(0);
            //List<ETCSplitDetailModel> splitProvince =sqlMapClient.queryForList("ZfkExitW_ORACLE.getsplitProvinceList",zfk);
            //暂时写死
            List<ETCSplitDetailModel> splitProvince =new ArrayList<>();
            ETCSplitDetailModel etsm=new ETCSplitDetailModel();
            etsm.setTollProvinceId(Config.tollProvinceId);
            etsm.setExTollLaneId(TypeTransUtil.transIDToLaneID(zfk.getKeyPressInfo()));
            etsm.setEnTollLaneId(zfk.getEntryStation()==0?TypeTransUtil.transIDToLaneID(zfk.getKeyPressInfo()):em.getEnTollLaneId());
            etsm.setEnTime(zfk.getEntryStation()==0?DateUtil.formatDateTimes(zfk.getExitTime()):DateUtil.formatDateTimes(zfk.getEntryTime()));
            etsm.setExTime(DateUtil.formatDateTimes(zfk.getExitTime()));
            etsm.setTollFee(em.getFee().toString());
            etsm.setDiscountFee(zfk.getFreeMoney().intValue()+"");
            etsm.setRateVersion("6520180101001|6520180101002");
            splitProvince.add(etsm);
            em.setSplitProvince(splitProvince);
            amount+=(zfk.getStoreMoney()+zfk.getTallyMoney());
            data.add(em);
        }
        ETCTransactionUploadRequest request = new ETCTransactionUploadRequest();
        //填充数据
        request.setTransaction(data);
        request.setTollProvinceId(Config.tollProvinceId);
        request.setIssuerId(TypeTransUtil.netIDToIssueID(netID));
        //TODO 这里需要完善
        request.setCount(list.size());
        request.setAmount(amount);
        request.setMessageId((long)MessageID);
        request.setReqSender(Config.tollProvinceId);

        //TRANSACTION_ETCTU_REQ_SENDER_yyyyMMddHHmmssSSS.zip
        //request.setFileName("TRANSACTION_ETCTU_REQ_"+Config.tollProvinceId+"_"+DateUtil.getFullDateStringSSS()+".json");
        //log.info(request.toJson());
        log.info("开始上传文件："+request.getFilename());
        FileTools.string2File(Constants.UPLOAD_PATH_EXPANDCLEARDOWN, request.toJson(), request.getFilename(), true);

        try {
            ETCTransactionUploadResponse response = LwClientHelper.binPostUrl(request);
            log.info("发行方："+netID+"交易包号："+MessageID+"上传成功："+response.toJson());
            if(response!=null&&response.getInfo().equals("成功！")){

                //Date nowTime= new Date();
                //使用部中心接收时间做为上传时间
                Date nowTime= DateUtil.formatDateTime6(response.getReceiveTime());
                if(change){
                    //修改交易包号
                    Map map = new HashMap();
                    map.put("messageID",MessageID);
                    map.put("paraid", Constants.MESSAGEID_ETCTRANSACTION);
                    configParaDicDao.EditMessageID(map);
                   // sqlMapClient.update("Base_ORACLE.EditMessageID",map);
                }
                //修改流水上传标识
                tbl_ZFKExitWaste zfk=null;
                for (int i = 0; i < list.size(); i++) {
                    zfk=list.get(i);
                    zfk.setMessageId((double)MessageID);
                    zfk.setPrintTime(nowTime);
                    zfk.setTransFlag(1);
                   // zfk.setExitTimeStr(DateUtil.formatDateTime(zfk.getExitTime()));
                    zfkExitWasteDao.EditZfkWasteUpfalg(zfk);
                  //  sqlMapClient.update("ZfkExitW_ORACLE.EditZfkWasteUpfalg",zfk);
                }
                //Tbl_DataExchangeList插入
                DataExchangeList dataExchangeList= new DataExchangeList();
                dataExchangeList.setMessageID(MessageID+"");
                dataExchangeList.setSenderID(Config.tollProvinceId);
                dataExchangeList.setReceiverID(request.getIssuerId());
                dataExchangeList.setProcessTime(nowTime);
                dataExchangeList.setMessageClass(1);
                dataExchangeList.setMessageType(7);
                dataExchangeList.setContentType(1);
                dataExchangeList.setResult(1);
                dataExchangeList.setRecCount(request.getCount());
                dataExchangeList.setRecAmount(request.getAmount());
                dataExchangeList.setVersion(0);
                dataExchangeList.setReplyFlag(1);
                dataExchangeList.setReplyTime(nowTime);
                dataExchangeList.setFileName(request.getFilename());
                dataExchangeList.setResultDesc("原始ETC交易上传成功");
                dataExchangeList.setSpare1(MessageID+"");
                dataExchangeList.setSpare3("原始ETC交易上传");
                //sqlMapClient.insert("Base_ORACLE.addDataExchangeList",dataExchangeList);
                //插入日志表

                //DataExchangeLog dataLog = addLog(request, 1,"原始交易上传成功",nowTime);

                //sqlMapClient.insert("Base_ORACLE.addDataExchangeLog",dataLog);
                flag=true;

                //更新上传参数
                SeverRun serverRun =new SeverRun();
                serverRun.setId(Constants.CONTROL_ETCTRANSACTIONUPLOAD_PARAM);
                serverRun.setDateValue(DateUtil.formatDateTime6(response.getReceiveTime()));
                severRunDao.editSeverRun(serverRun);
                //sqlMapClient.update("Base_ORACLE.editSeverRun",serverRun);

                log.info("发行方："+netID+"交易包号："+MessageID+"系统更新成功");
            }

        } catch (IOException e) {
            log.info(e.getMessage());
            if(change){
                log.info("IO异常更新交易包号，修改上传流水");
                //修改交易包号
                Map map = new HashMap();
                map.put("messageID",MessageID);
                map.put("paraid", Constants.MESSAGEID_ETCTRANSACTION);
                configParaDicDao.EditMessageID(map);
                //sqlMapClient.update("Base_ORACLE.EditMessageID",map);
                //修改流水上传标识
                tbl_ZFKExitWaste zfk=null;
                for (int i = 0; i < list.size(); i++) {
                    zfk=list.get(i);
                    zfk.setMessageId((double)MessageID);
                    zfk.setPrintTime(new Date());
                    zfk.setTransFlag(0);
                   // zfk.setExitTimeStr(DateUtil.formatDateTime(zfk.getExitTime()));
                    zfkExitWasteDao.EditZfkWasteUpfalg(zfk);
                   // sqlMapClient.update("ZfkExitW_ORACLE.EditZfkWasteUpfalg",zfk);
                }
            }
            //失败插入日志表
           // DataExchangeLog dataLog = addLog(request, 0,"原始交易上传失败IO异常",new Date());
           // sqlMapClient.insert("Base_ORACLE.addDataExchangeLog",dataLog);


        } catch (ApiRequestException apie) {
            //TODO 系统自定义异常处理，各省补全
            apie.printStackTrace();
            log.error("错误码："+apie.getErrCode()+" 错误信息："+apie.getMessage());
            //失败插入日志表
           // DataExchangeLog dataLog = addLog(request, 0, apie.getMessage(),new Date());
           // sqlMapClient.insert("Base_ORACLE.addDataExchangeLog",dataLog);

            //判断异常标识分类处理
            //704 apie.getErrCode()

            if(apie.getErrCode()==703||apie.getErrCode()==704){
                /**解析apie.getMessage(),获取异常数据ID**/
                String str = apie.getMessage();

                if(str.contains("000000000000000000000")&& str.contains("tollLane不存在")){
                    for (int i = 0; i < request.getTransaction().size(); i++) {
                        ETCTransactionModel em = new ETCTransactionModel();
                        em=request.getTransaction().get(i);
                        if(em.getEnTollLaneId().equals("000000000000000000000")){
                            log.info("交易上传ID"+em.getId()+"入口车道号不正确上传失败！");
                            //更新该交易上传状态为-10
                            zfkExitWasteDao.EditZfkWasteErrorFlag(em.getId());
                           // sqlMapClient.update("ZfkExitW_ORACLE.EditZfkWasteErrorFlag",em.getId());
                            //记录异常数据
                           // DataExchangeLog errorLog = TypeTransUtil.getErrorLog(em.getId(), MessageID+"","业务校验失败：tollLane不存在", request.getIssuerId());
                           // sqlMapClient.insert("Base_ORACLE.addDataExchangeLog",errorLog);
                        }
                    }
                }else{
                    String[] errorList = str.split("ID:");
                    if(errorList!=null&&errorList.length>0){//如果存在异常数据
                        //去重复ID
                        String errorID="0";
                        for (int i=1; i<errorList.length; i++) {
                            errorID = errorList[i].split(",")[0];
                            log.info("交易上传ID"+errorID+"上传失败！");
                            //更新该交易上传状态为-10
                            //zfkExitWasteDao.EditZfkWasteErrorFlag(em.getId());
                            //sqlMapClient.update("ZfkExitW_ORACLE.EditZfkWasteErrorFlag",errorID);
                            //记录异常数据
                           // DataExchangeLog errorLog = TypeTransUtil.getErrorLog(errorID, MessageID+"",errorList[i], request.getIssuerId());
                          //  sqlMapClient.insert("Base_ORACLE.addDataExchangeLog",errorLog);
                        }

                    }
                }
            }
            if(apie.getErrCode()==707){
                //修改流水上传标识
                log.error("错误码："+apie.getErrCode()+" 错误信息："+apie.getMessage());
                log.info("交易包ID"+MessageID+"上传重复，批量更新为上传成功！");
                Map map = new HashMap();
                map.put("messageId",MessageID);
                map.put("cardNetID",netID);
                zfkExitWasteDao.EditZfkWasteUpfalgRepeat(map);
               // sqlMapClient.update("ZfkExitW_ORACLE.EditZfkWasteUpfalgRepeat",map);

            }


        }catch(Exception e){
            //String msg= e.getMessage().length()>=500?e.getMessage().substring(0, 500):e.getMessage();
            String msg=TypeTransUtil.getErrorMessage(e.getMessage()) ;
            throw new Exception("ETC交易上传请求响应失败:"+msg);
        }
        return flag;



    }
}
